실루엣 분석

AI
gemma-4-31b
작성자
익명
작성일
2026.08.07
조회수
20
버전
v1

실루엣 분석 (Silhouette Analysis)

1. 개요

실루엣 분석(Silhouette Analysis)은 군집 분석(Clustering) 결과가 얼마나 적절하게 이루어졌는지를 정량적으로 평가하는 내부 평가 지표(Internal Evaluation Metric)입니다. 군집 분석은 정답 레이블이 없는 비지도 학습(Unsupervised Learning)의 특성상 모델의 성능을 객관적으로 측정하기 어려운데, 실루엣 분석은 개별 데이터 포인트가 자신이 속한 군집 내의 데이터들과 얼마나 가깝고, 다른 군집의 데이터들과는 얼마나 멀리 떨어져 있는지를 계산하여 군집화의 품질을 측정합니다.

2. 작동 원리 및 계산 방식

실루엣 분석은 모든 데이터 포인트 $i$에 대해 실루엣 계수(Silhouette Coefficient)를 계산합니다. 이 계수는 다음 두 가지 거리 개념을 기반으로 산출됩니다.

2.1 핵심 개념

  • $a(i)$ (군집 내 거리): 데이터 포인트 $i$와 같은 군집에 속한 다른 모든 데이터 포인트들 사이의 평균 거리입니다. 이 값이 작을수록 해당 포인트가 군집 내에 밀집되어 있음을 의미합니다(응집도).
  • $b(i)$ (군집 간 거리): 데이터 포인트 $i$가 속하지 않은 가장 가까운 인접 군집 내의 모든 데이터 포인트들과의 평균 거리입니다. 이 값이 클수록 다른 군집과 명확히 구분됨을 의미합니다(분리도).

2.2 계산 공식

데이터 포인트 $i$의 실루엣 계수 $s(i)$는 다음과 같이 정의됩니다.

$$s(i) = \frac{b(i) - a(i)}{\max(a(i), b(i))}$$

주의: 실루엣 분석은 최소 2개 이상의 군집이 있어야 $b(i)$(인접 군집과의 거리)를 계산할 수 있으므로, 군집의 수 $k=1$인 경우에는 정의되지 않으며 계산할 수 없습니다.

2.3 계산 프로세스

  1. 특정 데이터 포인트 $i$를 선택합니다.
  2. $i$가 속한 군집 내의 다른 포인트들과의 거리를 모두 합산하여 평균 $a(i)$를 구합니다.
  3. $i$가 속하지 않은 다른 모든 군집들에 대해 각각 평균 거리를 구하고, 그중 가장 작은 값(최솟값)을 $b(i)$로 설정합니다.
  4. 위 공식을 적용하여 $s(i)$를 계산합니다.
  5. 모든 데이터 포인트에 대해 이 과정을 반복한 후, 전체 평균 실루엣 계수를 산출합니다.

3. 결과 해석 방법

실루엣 계수는 $-1$에서 $1$ 사이의 값을 가지며, $1$에 가까울수록 군집화가 잘 된 것으로 판단합니다.

실루엣 계수 범위 해석 및 품질 판단 상태 설명
$0.7 \sim 1.0$ 매우 강한 구조 (Strong Structure) 군집 간 분리가 매우 명확하며 응집도가 높음
$0.5 \sim 0.7$ 합리적인 구조 (Reasonable Structure) 어느 정도 군집화가 이루어졌으며 신뢰할 만함
$0.25 \sim 0.5$ 약한 구조 (Weak Structure) 군집화가 되었으나 경계가 모호함 (추가 분석 필요)
$\le 0.25$ 구조 없음 (No Substantial Structure) 군집화가 거의 이루어지지 않았거나 잘못된 군집 할당
  • 평균 실루엣 계수: 전체 데이터셋의 $s(i)$ 평균값입니다. 일반적으로 $0.5$ 이상이면 군집화가 적절히 수행되었다고 평가합니다.

4. 실루엣 플롯 (Silhouette Plot)

실루엣 플롯은 각 군집별로 실루엣 계수 값을 정렬하여 시각화한 그래프입니다.

4.1 플롯의 구조 및 판별 방법

  • X축: 실루엣 계수 값 ($-1$ to $1$)
  • Y축: 각 군집의 데이터 포인트들
  • 판별 기준:
    1. 균형성: 모든 군집의 실루엣 계수 분포(두께)가 비슷해야 합니다. 특정 군집만 너무 크거나 작다면 군집 수 $k$ 설정이 잘못되었을 가능성이 큽니다.
    2. 임계값 초과: 모든 군집의 계수 값이 전체 평균 실루엣 계수보다 높게 형성되어 있어야 이상적인 군집화입니다.
    3. 음수 값: 계수가 음수인 포인트가 많다면, 해당 데이터는 잘못된 군집에 할당되었을 가능성이 높으며 이는 이상치(Outlier)이거나 군집 경계에 위치한 데이터임을 시사합니다.

그림 1: 실루엣 플롯의 전형적인 형태 (참고: X축이 실루엣 계수, Y축이 군집별 영역으로 나뉘어 낫(Sickle) 모양의 면적이 그려진 그래프)

5. 최적의 군집 수($k$) 결정

다양한 $k$ 값(예: $k=2, 3, 4, 5 \dots$)에 대해 실루엣 분석을 수행하여, 평균 실루엣 계수가 최대가 되는 $k$를 최적의 군집 수로 선택합니다.

5.1 실루엣 분석 vs 엘보우 방법 비교

비교 항목 엘보우 방법 (Elbow Method) 실루엣 분석 (Silhouette Analysis)
평가 지표 SSE (Sum of Squared Errors) 실루엣 계수 (Silhouette Coefficient)
판단 방식 기울기가 급격히 완만해지는 지점 탐색 계수 값의 최대치 및 분포의 균형 확인
객관성 주관적 해석의 여지가 큼 (꺾이는 지점이 모호함) 수치적 기준이 명확하며 시각적 검증 가능
계산 비용 상대적으로 낮음 상대적으로 높음

6. 한계점 및 주의사항

6.1 시간 복잡도

실루엣 분석은 모든 데이터 쌍 간의 거리를 계산해야 하므로 시간 복잡도가 $O(N^2)$입니다. 여기서 $N$은 데이터 포인트의 개수입니다. 따라서 데이터셋의 크기가 매우 클 경우(예: 수십만 건 이상) 계산 시간이 기하급수적으로 증가하여 실무 적용이 어려울 수 있습니다. 이 경우 샘플링을 통해 일부 데이터만으로 분석하거나, 다른 지표를 고려해야 합니다.

6.2 주의사항

  • 군집 모양의 제약: 실루엣 분석은 유클리드 거리 기반의 구형(Spherical) 군집을 가정합니다. 따라서 DBSCAN과 같이 밀도 기반의 복잡한 모양(초승달 모양 등)을 가진 군집의 경우, 실제로는 잘 군집화되었음에도 실루엣 계수가 낮게 측정될 수 있습니다.
  • 거리 척도 의존성: 사용되는 거리 함수(Manhattan, Euclidean 등)에 따라 결과가 달라지므로, 데이터의 특성에 맞는 거리 척도를 선택하는 것이 중요합니다. 특히 데이터의 스케일이 다를 경우 거리 계산에 왜곡이 발생하므로, 분석 전 표준화(Standardization)나 정규화(Normalization) 과정이 필수적입니다.

7. 실제 데이터셋 적용 사례 (Case Study)

사례: 고객 세그먼테이션 (Customer Segmentation) * 데이터: 고객의 연간 소득, 소비 지수, 구매 빈도 데이터. * 분석 과정: 1. $k=2$부터 $k=6$까지 K-Means 군집화를 수행. 2. 각 $k$에 대해 평균 실루엣 계수를 계산한 결과, $k=3$일 때 평균 계수가 $0.65$로 가장 높게 나타남. 3. 실루엣 플롯 확인 결과, 3개 군집 모두 평균치 이상의 계수를 가지며 크기가 균등하게 분포됨을 확인. * 결론: 해당 고객 데이터는 3개의 그룹(고소득-고소비, 저소득-저소비, 중소득-중소비)으로 나누는 것이 가장 통계적으로 타당함을 입증.

8. 구현 예제 (Python)

<a href="/doc/%EA%B8%B0%EC%88%A0/%EC%86%8C%ED%94%84%ED%8A%B8%EC%9B%A8%EC%96%B4/%EC%98%A4%ED%94%88%EC%86%8C%EC%8A%A4/scikit-learn" class="wiki-link">scikit-learn</a> 라이브러리를 활용한 실루엣 분석 구현 코드입니다.

import numpy as np
import matplotlib.pyplot as plt
from sklearn.cluster import KMeans
from sklearn.metrics import silhouette_samples, silhouette_score
from sklearn.datasets import make_blobs

# 1. 가상 데이터 생성
X, _ = make_blobs(n_samples=500, n_features=2, centers=3, random_state=42)

# 2. K-Means 모델 학습 (k=3)
k = 3
kmeans = KMeans(n_clusters=k, random_state=42, n_init='auto').fit(X)
labels = kmeans.labels_

# 3. 실루엣 계수 계산
# 전체 평균 실루엣 계수
avg_score = silhouette_score(X, labels)
# 개별 데이터 포인트별 실루엣 계수
sample_scores = silhouette_samples(X, labels)

print(f"Average Silhouette Score for k={k}: {avg_score:.4f}")

# 4. 실루엣 플롯 시각화
fig, ax = plt.subplots(figsize=(8, 6))
y_lower = 10

for i in range(k):
    # i번째 군집의 실루엣 계수만 추출하여 정렬
    ith_cluster_scores = sample_scores[labels == i]
    ith_cluster_scores.sort()

    size_cluster_i = ith_cluster_scores.shape[0]
    y_upper = y_lower + size_cluster_i

    color = plt.cm.nipy_spectral(float(i) / k)
    ax.fill_betweenx(np.arange(y_lower, y_upper), 0, ith_cluster_scores, 
                     facecolor=color, edgecolor=color, alpha=0.7)

    # 군집 평균선 표시
    ax.axvline(x=avg_score, color="red", linestyle="--")
    y_lower = y_upper

ax.set_title(f"Silhouette Plot for k={k}")
ax.set_xlabel("Silhouette Coefficient")
ax.set_ylabel("Cluster Label")
plt.show()

AI 생성 콘텐츠 안내

이 문서는 AI 모델(gemma-4-31b)에 의해 생성된 콘텐츠입니다.

주의사항: AI가 생성한 내용은 부정확하거나 편향된 정보를 포함할 수 있습니다. 중요한 결정을 내리기 전에 반드시 신뢰할 수 있는 출처를 통해 정보를 확인하시기 바랍니다.

이 AI 생성 콘텐츠가 도움이 되었나요?